import axios from "axios";
import store from '../store'
import router from '../router'
import {getTokenApi} from '../api/api'
import { ElMessage } from 'element-plus'

export default {
  install(app) {
    
    axios.defaults.baseURL = import.meta.env.VITE_BASE_URL

    // 请求拦截
    axios.interceptors.request.use(
      (request) => {
        let path = request.url
        if(path === '/captcha' || path === '/cms/sms/verify/code' || path === '/zcyt-auth/oauth/token') {
          request.headers['Authorization'] = 'Basic WkNZVC1NRVJDSEFOVDo2YmQ3NGZhN2Q3MTU5YWMyMzcwM2E1NDhjMDg5ZThkZQ=='
          return request
        } else {
          request.headers['Authorization'] = `Bearer ${store.state.accessToken}`
          return request
        }
      },
      (error) => {
        return Promise.reject(error)
      }
    )
    
    let isRefreshing  = false // 标记是否正在刷新token
    let requests = [] // 存储待重发请求的数组
    // 响应拦截
    axios.interceptors.response.use(
      (response) => {
        if (response.status === 200) {
          return response.data
        }
      },
      (error) => {
        if(error.response.status === 401 && !error.config.url.includes('/zcyt-auth/oauth/token')) { // 401请求token过期
          const { config } = error
          if(!isRefreshing) {
            isRefreshing = true
            let formData = new FormData()
            formData.append('grant_type', 'refresh_token')
            formData.append('refresh_token', store.state.refreshToken)
            // 无感刷新token
            return getTokenApi(formData).then(res => {
              if(res.code === '200') {
                const { access_token, refresh_token } = res.data
                window.localStorage.setItem('accessToken', access_token)
                window.localStorage.setItem('refreshToken', refresh_token)
                store.commit('accessToken', access_token)
                store.commit('refreshToken', refresh_token)
                requests.forEach((cb) => cb(access_token))  // token 刷新后将数组的方法重新执行
                requests = [] // 重新请求完清空
                return axios(config) // 重新请求数据并返回
              }
            }).catch(err => {
              router.push({name: 'login'})
              return Promise.reject(err)
            }).finally(() => {
              isRefreshing = false
            })
          } else {
            // 返回未执行 resolve 的 Promise 即多个请求时候，将其他请求缓存到requests中
            return new Promise(resolve => {
              // 用函数形式将 resolve 存入，等待刷新后再执行
              requests.push(token => {
                config.headers.Authorization = `Bearer ${token}`
                resolve(axios(config))
              })
            })
          }
        } else {
          ElMessage.error(error.response.data.message)
          return Promise.reject(error)
        }
      }
    )
    app.config.globalProperties.$http = axios
  }
}